const { ccclass, property } = cc._decorator;
import MonstersBilder from './MonstersBilder';
import MyEnums from '../MyEnums';
import RandomProp from '../RandomProp/RandomPropControl';
import SoundMgr from '../SoundMgr';
import TargetBase from '../SkillAttack/TargetBase';


@ccclass
export default class MonsterControl extends cc.Component {
    @property(cc.Node)
    Body: cc.Node = null;
    @property(cc.Node)
    BarNode: cc.Node = null;
    @property(cc.Node)
    followNode: cc.Node = null;
    @property(cc.Node)
    SkillsNode: cc.Node = null;
    @property
    attribute: number = 0;//攻击类型(火，水，风，毒。。。。)
    @property
    life: number = 100//生命值
    @property()
    jumpLong: number = 70;//跳跃距离
    @property
    isTrace: boolean = false;//是否追踪目标
    @property
    canOutWay: boolean = false;//是否允许跳出当前WayNode
    @property()
    jumpHeight: number = 350;//跳跃高度
    @property
    jumpTime: number = 1.5;//跳跃间隔
    @property
    lifeMax: number = 0;
    @property
    attackDamage: number = 0;//基础攻击力
    @property
    _RandomProp: RandomProp = null;
    @property
    _SoundMgr: SoundMgr = null;

    monstersBilder: MonstersBilder = null;
    faceTo: number = 1;//跳跃方向
    maxLife: number = 100;
    slownessLong: number = 50;//减速跳跃距离
    slownessHeight: number = 200;//减速跳跃高度
    StatusTypeList: boolean[] = [];//标记是否已经开启某种状态

    _jumpDistance: number = 0;
    _Rbody: cc.RigidBody = null;
    _Collider: cc.PhysicsBoxCollider = null;
    _Anim: cc.Animation = null;
    _blastSprite: cc.Sprite = null;
    _Status: number = MyEnums.MonsterStatus.birth;
    _newLocity: cc.Vec2 = null;
    _isContact: boolean = false;
    _isJumping: boolean = false;
    _uuidFootCollider: string = null;
    _uuidWayCollider: string = null;
    _progress: cc.ProgressBar = null;
    _wayNode: cc.Node = null;


    onLoad() {
        this.StatusTypeList = [false, false, false, false, false, false, false];
        this.node.group = this.node.parent.group;
        this.maxLife = this.life;
        this.BarNode.active = false;
        this.lifeMax = this.life;
        this._progress = this.BarNode.getComponent(cc.ProgressBar);
        this._Rbody = this.node.getComponent(cc.RigidBody);
        this._Collider = this.node.getComponent(cc.PhysicsBoxCollider);
        this._Collider.friction = 1;
        this._Collider.tag = TagMonsterBody;
        this._Collider.size = new cc.Size(this.Body.width - 5, this.Body.height - 5);
        let AttackCollider = this.node.getComponent(cc.CircleCollider);
        AttackCollider.radius = this.Body.width / 2 + 5;
        AttackCollider.tag = TagMonsterBody;
        this._Anim = this.node.getComponent(cc.Animation);
        this._Anim.on(cc.Animation.EventType.FINISHED, this.onEndAnim, this);
        this.schedule(this.jump, this.jumpTime);
    }
    onEndAnim() {
        if (!this._Anim.currentClip)
            return;
        let name = this._Anim.currentClip.name;
        if (name == "attack") {
            this._Status = MyEnums.MonsterStatus.blasted;
            this.onMonsterDestroy();
        }
        else if (name == "birth") {
            this._Rbody.awake = true;
            this.Body.opacity = 255;
            this._Status = MyEnums.MonsterStatus.await;
        }
        else if (name == "jumpEnd") {
            this._isJumping = false;
            this._Status = MyEnums.MonsterStatus.await;
        }
        else if (name == "jumpBegin") {
            this.jumpBegin();
        }
        else
            this._Status = MyEnums.MonsterStatus.await;
    }
    playAnim(name: string): boolean {
        if (this._Status == MyEnums.MonsterStatus.blasted || this._Status == MyEnums.MonsterStatus.birth || this._Status == MyEnums.MonsterStatus.attack)
            return false;
        let currentname = this._Anim.currentClip.name;
        if (currentname != name) {
            this._Anim.play(name)
            switch (name) {
                case "jumpBegin":
                    this._Status = MyEnums.MonsterStatus.JumpBegin;
                    break;
                case "jumpEnd":
                    this._Status = MyEnums.MonsterStatus.jumpEnd;
                    break;
                case "attack":
                    this._Status = MyEnums.MonsterStatus.attack;
                    break;
            }
            return true;
        }
        return false;
    }
    jump() {
        if (this.StatusTypeList[MyEnums.SkillStatusType.freeze] || this.StatusTypeList[MyEnums.SkillStatusType.dizziness])
            return;
        if (this._Status == MyEnums.MonsterStatus.await && this._isContact) {
            this.getLocity();
            if (!this.canOutWay) {
                let dis = this.getDistance(this._newLocity);
                if (this.checkOut(dis)) {
                    return;
                }
            }
            this._isJumping = true;
            this.setFaceto(this.faceTo);
            this.playAnim("jumpBegin");
        }
    }
    jumpBegin() {
        if (this._Status == MyEnums.MonsterStatus.JumpBegin) {
            this._Status = MyEnums.MonsterStatus.jimpIng;
            this._Rbody.linearVelocity = this._newLocity;
        }
    }
    setFaceto(faceto: number) {
        this.faceTo = faceto;
        this.node.scaleX = this.faceTo;
        this.followNode.scaleX = this.faceTo;
    }
    getLocity() {
        if (this.isTrace) {
            let heroP = HeroHelper.getInstance().GetWorldPosition();
            let thisP = this.node.convertToWorldSpaceAR(cc.v2(0, 0));
            if (heroP) {
                let Px = heroP.x - thisP.x;
                if (Px > 0)
                    this.faceTo = 1;
                else
                    this.faceTo = -1;
            }
        }
        else {
            let index = Math.random();
            if (index >= 0.5) {
                this.faceTo = 1;
            }
            else {
                this.faceTo = -1;
            }
        }
        if (this.StatusTypeList[MyEnums.SkillStatusType.purifica]) {
            this.faceTo = 0 - this.faceTo;
        }
        if (this.StatusTypeList[MyEnums.SkillStatusType.slowness]) {
            this._newLocity = new cc.Vec2(this.slownessLong * this.faceTo, this.slownessHeight);
        }
        else {
            this._newLocity = new cc.Vec2(this.jumpLong * this.faceTo, this.jumpHeight);
        }
    }
    checkOut(Distance: number) {
        if (this._wayNode) {
            let wayP = this._wayNode.convertToWorldSpaceAR(cc.v2(0, 0));
            let nodeP = this.node.convertToWorldSpaceAR(cc.v2(0, 0));
            let P = nodeP.x - wayP.x;//相对位置
            if (Math.abs(Distance * this.faceTo + P) > this._wayNode.width / 2) {
                //尝试减小跳跃距离
                if (Math.abs(Distance / 2 * this.faceTo + P) > this._wayNode.width / 2)
                    return true;
                else {
                    this._newLocity.x = this._newLocity.x / 2;
                }
            }
        }
        return false;
    }
    getDistance(velocity: cc.Vec2): number {
        if (this._jumpDistance == 0) {
            let gravity = cc.director.getPhysicsManager().gravity;
            let scale = this._Rbody.gravityScale;
            this._jumpDistance = (2 * velocity.x * velocity.y) / (gravity.y * scale);
            this._jumpDistance = Math.abs(this._jumpDistance);
        }
        return this._jumpDistance;
    }
    birth() {
        this._Anim.play('birth');
        this._Status = MyEnums.MonsterStatus.birth;
        if (!this._blastSprite) {
            this._blastSprite = this.node.addComponent(cc.Sprite);
        }
    }
    checkBusy() {
        if (this._Status == MyEnums.MonsterStatus.await)
            return false;
        else
            return true;
    }
    setBusy() {
        if (this._Status == MyEnums.MonsterStatus.await) {
            this._Status = MyEnums.MonsterStatus.otherBusy;
        }
    }
    setNotBusy() {
        if (this._Status == MyEnums.MonsterStatus.otherBusy) {
            this._Status = MyEnums.MonsterStatus.await;
        }
    }
    onBeginContact(contact, selfCollider, otherCollider) {
        let wayid = otherCollider.node.uuid;
        var worldManifold = contact.getWorldManifold();
        var normal = worldManifold.normal;
        if (normal.y < -0.8) {
            this._uuidFootCollider = wayid;
            this._wayNode = otherCollider.node;
            this._isContact = true;
            if (otherCollider.tag == TagWayBody1 || otherCollider.tag == TagWayBody1) {
                this._uuidWayCollider = wayid;
            }
            else if (otherCollider.tag == TagAbyss) {
                this.onMonsterDestroy(true);
                return;
            }
            if (this._Status == MyEnums.MonsterStatus.jimpIng || this._Status == MyEnums.MonsterStatus.await) {
                this.playAnim("jumpEnd");
            }
        }
    }
    onEndContact(contact, selfCollider, otherCollider) {
        if (this._uuidFootCollider == otherCollider.node.uuid) {
            this._isContact = false;
        }
    }
    doAttack(): boolean {//开始攻击
        if (this.StatusTypeList[MyEnums.SkillStatusType.purifica] || this.StatusTypeList[MyEnums.SkillStatusType.dizziness] || this.StatusTypeList[MyEnums.SkillStatusType.freeze])
            return false;
        if (this._Status != MyEnums.MonsterStatus.attack) {
            this.playAnim("attack");
            this._SoundMgr.play("_swell");
            return true;
        }
        return false;
    }
    onMonsterDestroy(self: boolean = false) {//回收或销毁
        if (this._RandomProp && !self) {
            let p1 = this.Body.convertToWorldSpaceAR(cc.Vec2.ZERO);
            this._RandomProp.getPickup(p1);
        }
        if (this.monstersBilder) {
            this.life = this.maxLife;
            this.BarNode.active = false;
            this._Status = MyEnums.MonsterStatus.await;
            this.node.getComponent(cc.Sprite).spriteFrame = null;
            this.node.getChildByName("Skills").children.forEach((item) => {
                if (item.name != "Transfer" && item.name != "Blast") {
                    item.destroy();
                }
            });
            this.node.getChildByName("follow").getChildByName("lifeValue").destroyAllChildren();

            let target = this.node.getComponent(TargetBase);
            target.clearSkills();

            this.node.active = false;
            this.monstersBilder.recycleMonster(this.node);
        }
        else {
            this.node.destroy();
        }
        if (!self) //是否是自杀的
            HeroManager.getInstance().killCounts++;
    }
    //设置血量并更新血条
    SetLife(lifeValue: any): boolean {
        if (this._Status == MyEnums.MonsterStatus.attack || this._Status == MyEnums.MonsterStatus.blasted || this._Status == MyEnums.MonsterStatus.birth)
            return false;
        this.life += lifeValue;
        if (this.life <= 0) {
            this.life = 0;
            this.playAnim("attack");
            this._SoundMgr.play("_howl");
        }
        else if (this.life > this.lifeMax)
            this.life = this.lifeMax;
        this.BarNode.active = true;
        this._progress.progress = this.life / this.maxLife;
        return true;
    }
    SetStatusType(type: number, bl: boolean) {
        this.StatusTypeList[type] = bl;
    }
}
